#include "GT20L16P1Y.h"

unsigned short unicode_zf[31] =
{
    0x3000,0x3001,0x3002,0x00b7,0x02c9,0x02c7,0x00a8,0x3003,0x3005,0x2014,0xff5e,0x2016,0x2026,
    0x2018,0x2019,0x201c,0x201d,0x3014,0x3015,0x3008,0x3009,0x300a,0x300b,0x300c,0x300d,0x300e
    ,0x300f,0x3016,0x3017,0x3010,0x3011
};
unsigned char find_zf_tab(unsigned short unicode)
{
    unsigned char i;
    for( i=0; i < 31; i++ )
    {
    if( unicode == unicode_zf[i] )
    break;
    }
    if(i==31)
    return(0);
    return(i);
}

int GT20L16P1Y::utf8ToUnicode(const char* utf8, int* unicode) {
    unsigned char* p = (unsigned char*)utf8;
    int len = 0;
    int count = 0;
    int result = 0;

    // 判断UTF-8编码的字符长度
    if ((*p & 0xF0) == 0xF0) {
        len = 4;
    } else if ((*p & 0xE0) == 0xE0) {
        len = 3;
    } else if ((*p & 0xC0) == 0xC0) {
        len = 2;
    } else {
        len = 1;
    }

    // 根据长度计算Unicode码
    for (int i = 0; i < len; i++) {
        // Serial.print(*p,HEX);
        // Serial.print(" ");
        if(len == 1){
            result = *p;
        }else{
            result <<= 6;
            result += *p++ & 0x3F;
        }
        count++;
    }

    // 判断是否为合法的UTF-8编码
    if (count != len) {
        return -1;
    }

    *unicode = result;
    return len;
}

int GT20L16P1Y::utf8StringToUnicode(const char* utf8, int* unicode) {
    int len = 0;
    int totalLen = 0;
    int result = 0;

    while (*utf8 != '\0') {
        len = utf8ToUnicode(utf8, &result);
        if (len == -1) {
            return -1;
        }

        *unicode++ = result;
        utf8 += len;
        totalLen++;
    }

    return totalLen;
}

void GT20L16P1Y::utf8ChineseToUnicode(const char* utf8, unsigned short* unicode) {
    unsigned char* p = (unsigned char*)utf8;

    // 获取UTF-8编码的第一个字节
    unsigned char byte1 = *p++;

    // 获取UTF-8编码的第二个字节
    unsigned char byte2 = *p++;

    // 获取UTF-8编码的第三个字节
    unsigned char byte3 = *p++;

    // 拼接得到Unicode编码的值
    unsigned short value = ((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);

    // 将Unicode编码的值存储在2字节的数组中
    unicode[0] = value;
}

void GT20L16P1Y::utf8ToUnicode2Bytes(const char* utf8, unsigned char* unicode) {
    unsigned char* p = (unsigned char*)utf8;

    // 获取UTF-8编码的第一个字节
    unsigned char byte1 = *p++;

    // 获取UTF-8编码的第二个字节
    unsigned char byte2 = *p++;

    // 拼接得到Unicode编码的值
    unsigned short value = ((byte1 & 0x1F) << 6) | (byte2 & 0x3F);

    // 将Unicode编码的值存储在2字节的数组中
    unicode[0] = (value >> 8) & 0xFF;
    unicode[1] = value & 0xFF;
}

void GT20L16P1Y::begin(){

    pinMode(FONT_CS, OUTPUT);
    // pinMode(FONT_SCL, OUTPUT);
    // pinMode(FONT_MISO, INPUT);
    // pinMode(FONT_MOSI, OUTPUT);

    // SPI.begin(FONT_SCL, FONT_MISO, FONT_MOSI, FONT_CS);
    _settings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
}

void GT20L16P1Y::deg270_16bit(){
    
    for(int i=0; i<16; i++){
        uint8_t data = 0x00;
        int offset = (i < 8) ? 0 : 8;
        for(int j=0; j<8; j++){
            data <<= 1;
            data += (_matrixdata16[j + offset] >> ((8 + i) % 8)) & 1;
        }
        _matrixdata16_deg90[i] = data;
    }
}

void GT20L16P1Y::deg270_32bit(){
    
    for(int i=0; i<16; i++){
        uint16_t data = 0x00;
        int offset = (i < 8) ? 0 : 16;
        for(int j=0; j<16; j++){
            data <<= 1;
            data += (_matrixdata32[j + offset] >> ((8 + i) % 8)) & 1;
        }
        _matrixdata32_deg90[i] = data;
    }
}

void GT20L16P1Y::fix_16bit(){
    for(int i=0; i<8; i++){
        uint16_t data = 0x00;
        data = (_matrixdata16[i + 8] << 8) + _matrixdata16[i];
        fixData_16[i] = data;
    }
}

void GT20L16P1Y::fix_32bit(){
    for(int i=0; i<16; i++){
        uint16_t data = 0x00;
        data = (_matrixdata32[i + 16] << 8) + _matrixdata32[i];
        fixData_32[i] = data;
    }
}

void GT20L16P1Y::readFont8x16(uint16_t unicode){
    //Serial.print("ASCII,0x");Serial.print(ASCIICODE, HEX); //10/07
    uint32_t Address = 0;
    /*ASCII文字*/
    int BaseAdd = 0;
    if( unicode >= 0x20 && unicode <= 0x7f )//latin 1
        Address = 16*(unicode-0x20)+ BaseAdd;
    else if( unicode >= 0xa0 && unicode <= 0xff )//latin 2
        Address = 16*(96+unicode-0xa0)+ BaseAdd;
    else if( unicode >= 0x100 && unicode <= 0x17f )//latin 3
        Address = 16*(96+96+unicode-0x100)+ BaseAdd;
    else if( unicode >= 0x1a0 && unicode <= 0x1cf )//latin 4
        Address = 16*(128+96+96+unicode-0x1a0)+ BaseAdd;
    else if( unicode >= 0x1f0 && unicode <= 0x1ff )//latin 5
        Address = 16*(48+128+96+96+unicode-0x1f0)+ BaseAdd;
    else if( unicode >= 0x210 && unicode <= 0x21f )//latin 6
        Address = 16*(16+48+128+96+96+unicode-0x210)+ BaseAdd;
    else if( unicode >= 0x1ea0 && unicode <= 0x1eff )//latin 7
        Address = 16*(16+16+48+128+96+96+unicode-0x1ea0)+ BaseAdd;
    else if( unicode >= 0x370 && unicode <= 0x3cf )//greek
        Address = 16*(96+16+16+48+128+96+96+unicode-0x370)+ BaseAdd;
    else if( unicode >= 0x400 && unicode <= 0x45f )//cyrillic 1
        Address = 16*(96+96+16+16+48+128+96+96+unicode-0x400)+ BaseAdd;
    else if( unicode >= 0x490 && unicode <= 0x4ff )//cyrillic 2
        Address = 16*(96+96+96+16+16+48+128+96+96+unicode-0x490)+ BaseAdd;
    else if( unicode >= 0x590 && unicode <= 0x5ff )//hebrew
        Address = 16*(112+96+96+96+16+16+48+128+96+96+unicode-0x590)+ BaseAdd;
    else if( unicode >= 0xe00 && unicode <= 0xe7f )//thai
        Address = 16*(112+112+96+96+96+16+16+48+128+96+96+unicode-0xe00)+ BaseAdd;
    else
        Address = BaseAdd;

    SPI.beginTransaction(_settings);
    digitalWrite(FONT_CS, HIGH);
    //   Serial.print("  Address = "); Serial.println(Address, HEX);
    digitalWrite(FONT_CS, LOW);  //通信開始
    SPI.transfer(0x03);
    SPI.transfer((Address >> 16)  & 0xff);
    //   SPI.transfer16(Address >> 16);
    SPI.transfer((Address >> 8)   & 0xff);
    SPI.transfer(Address        & 0xff);
    for (int i = 0; i < 16; i++)
    {
        _matrixdata16[i] = SPI.transfer(0x00);
        // Serial.print(" ");
        // Serial.print(SPI.transfer(0x00), HEX);
    }
    SPI.endTransaction();
    digitalWrite(FONT_CS, HIGH); 
    //   deg270_16bit();
    fix_16bit();
}

void GT20L16P1Y::readFont16x16(uint16_t UNICODE){
    uint32_t Address = 0;
    int ZFAdd = 36224; //字符的起始地址
    int HZAdd = 93452; //汉字的起始地址
    int Unicodetab = 45632;
    unsigned char buffer[2];
    if(UNICODE >= 0x4e00 && UNICODE < 0x9fa6 ) // Unicode 汉字区
    {
        Address = 2*(UNICODE-0x4e00);
        Address = Address + Unicodetab;
        //从字库中读取二个字节
        SPI.beginTransaction(_settings);
        digitalWrite(FONT_CS, HIGH);
        digitalWrite(FONT_CS, LOW);  //开始通信
        SPI.transfer(0x03);
        SPI.transfer((Address >> 16)  & 0xff);
        SPI.transfer((Address >> 8)   & 0xff);
        SPI.transfer(Address        & 0xff);
        for (int i = 0; i < 2; i++)
        {
            buffer[i] = SPI.transfer(0x00);
        }
        digitalWrite(FONT_CS, HIGH); //结束通信
        SPI.endTransaction();
        Address = 256*buffer[0]+buffer[1];
        Address = 32* Address + HZAdd;
        
    }
    else if(UNICODE >= 0xff01 && UNICODE <= 0xff5d ) //Unicode 字符区 1
        Address = 32*(31+UNICODE-0xff01)+ ZFAdd;
    else if(UNICODE == 0xffe3) //Unicode 字符区 2
        Address = 32*(31+93)+ ZFAdd;
    else if( UNICODE >= 0x3041 && UNICODE <= 0x3096 ) //Unicode 字符区 3
        Address = 32*(31+93+1+UNICODE-0x3041)+ ZFAdd;
    else if( UNICODE >= 0x30a1 && UNICODE <= 0x30f6 ) //Unicode 字符区 4
        Address = 32*(31+93+1+83+UNICODE-0x30a1)+ ZFAdd;
    else //Unicode 字符区 5
        Address = 32 * find_zf_tab(UNICODE)+ ZFAdd;
    SPI.beginTransaction(_settings);
    digitalWrite(FONT_CS, HIGH);
    digitalWrite(FONT_CS, LOW);  //开始通信
    SPI.transfer(0x03);
    SPI.transfer((Address >> 16)  & 0xff);
    SPI.transfer((Address >> 8)   & 0xff);
    SPI.transfer(Address        & 0xff);
    for (int i = 0; i < 32; i++)
    {
        _matrixdata32[i] = SPI.transfer(0x00);
    }
    SPI.endTransaction();
    digitalWrite(FONT_CS, HIGH); //结束通信
    // deg270_32bit();
    fix_32bit();
}

void GT20L16P1Y::readFontGB2312(uint16_t GB2312CODE){
    uint32_t Address = 0;
    uint8_t MSB = (GB2312CODE & 0xFF00) >> 8; //高字节
    uint8_t LSB = GB2312CODE & 0x00FF;  //低字节
    int ZFAdd = 36224; //表示汉字点阵在芯片中的字节地址
    int HZAdd = 93452;
    int GB2312tab = 87436; //转码表起始地址
    unsigned char buffer[2];
    if( MSB >= 0xA1 && MSB <= 0xA5 )//字符区
    {
        if(MSB == 0xA1 && LSB >= 0xA1 && LSB <= 0xBF )
            Address = 32*(LSB-0xA1)+ ZFAdd;
        else if(MSB == 0xA3 && LSB >= 0xA1 && LSB <= 0xFE )
            Address = 32*(31+LSB-0xA1)+ ZFAdd;
        else if(MSB == 0xA4 && LSB >= 0xA1 && LSB <= 0xF3)
            Address = 32*(31+94+LSB-0xA1)+ ZFAdd;
        else if(MSB == 0xA5 && LSB >= 0xA1 && LSB <= 0xF6)
            Address = 32*(31+94+83+LSB-0xA1)+ ZFAdd;
        else
            Address = ZFAdd;
    }
    else if( (MSB >= 0xB0 && MSB <= 0xD7)&&(LSB>=0xA1 && LSB <= 0xFE) )//汉字 5270
        Address = 32*( (MSB - 0xB0) * 94 + (LSB - 0xA1)+1)+ HZAdd;
    else if( (MSB >= 0xD8 && MSB <= 0xF7)&&(LSB>=0xA1 && LSB <= 0xFE))//汉字 5270~6763
    {
        Address = ((MSB - 0xD8) * 94 + (LSB - 0xA1) ) *2 + GB2312tab;
        SPI.beginTransaction(_settings);
        digitalWrite(FONT_CS, HIGH);
        digitalWrite(FONT_CS, LOW);  //开始通信
        SPI.transfer(0x03);
        SPI.transfer((Address >> 16)  & 0xff);
        SPI.transfer((Address >> 8)   & 0xff);
        SPI.transfer(Address        & 0xff);
        for (int i = 0; i < 2; i++)
        {
            buffer[i] = SPI.transfer(0x00);
        }
        digitalWrite(FONT_CS, HIGH); //结束通信
        SPI.endTransaction();
        Address = 32* (256*buffer[0]+buffer[1]) + HZAdd;
    }
    SPI.beginTransaction(_settings);
    digitalWrite(FONT_CS, HIGH);
    digitalWrite(FONT_CS, LOW);  //开始通信
    SPI.transfer(0x03);
    SPI.transfer((Address >> 16)  & 0xff);
    SPI.transfer((Address >> 8)   & 0xff);
    SPI.transfer(Address        & 0xff);
    for (int i = 0; i < 32; i++)
    {
        _matrixdata32[i] = SPI.transfer(0x00);
    }
    SPI.endTransaction();
    digitalWrite(FONT_CS, HIGH); //结束通信
    deg270_32bit();
    
}

